/**
 * Copyright (C) 2008 Christopher Allen Ogden
 *
 *     This file is part of Odysi.
 *
 *  Odysi is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Odysi is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Odysi.  If not, see <http://www.gnu.org/licenses/>.
 */
#pragma once

#include <string>
#include <stdexcept>
#include <stdio.h>
#include "packetHeaders.h"
#include "packet.h"

namespace genPacket {

    const int maxLoginNameLength = 16;
    const int maxPasswordLength = 16;

    /**
     * Stores a login packet.
     */
    struct LoginPacket
    {
        char cmd;        /**< The command byte. */
        char name[maxLoginNameLength];   /**< The username. */
        char pass[maxPasswordLength];   /**< The password. */
    };

    /**
     * Stores a simple packet.
     */
    struct SimplePacket
    {
        char cmd;   /**< The command byte. */
    };

    /**
     * Stores an add character packet.
     */
    struct AddCharacterPacket
    {
        char cmd;
        unsigned int x;
        unsigned int y;
        int z;
        unsigned int mobID;
        unsigned int id;
        float red;
        float green;
        float blue;
        float alpha;
    };

    /**
     * Move request packet.
     */
    struct MoveRequestPacket
    {
        char cmd;
        int dir;
    };

    /**
     * Move object.
     */
    struct MoveObjectPacket
    {
        char cmd;
        unsigned int id;
        int xOff;
        int yOff;
        int zOff;
    };

    /**
     * Generate a login packet.
     *
     * @param name  The login name.
     * @param pass  The login password.
     * @return      The packet.
     */
    Packet login(const std::string &name, const std::string &pass);

    /**
     * Generate a login OK packet.
     *
     * @return  The packet.
     */
    Packet loginOK(void);

    /**
     * Generate a login fail packet.
     *
     * @return  The packet.
     */
    Packet loginFail(void);

    Packet addCharacter(unsigned int x, unsigned int y, int z, unsigned int mobID, unsigned int id, float red, float green, float blue, float alpha);

    Packet moveObject(unsigned int id, int xOff, int yOff, int zOff);

    /**
     * Determine a packet length, given an input stream.  The stream is given
     * in the first parameter, along with the length of the stream.  This function
     * then uses the stream to determine the length required (amount of data) for
     * whatever packet sits at the front of the stream.  If it cannot be determined
     * because not enough information has been passed, it will return 0.
     *
     * @param packet    As much of the packet as is available.
     * @param length    The length.
     * @return          The packet length or 0 if undeterminable.
     */
    unsigned int getPacketLength(const unsigned char * const packet, unsigned int length);

    /**
     * Request move.
     *
     * @param dir   Direction to move in.
     */
    Packet moveRequest(int dir);

}
